package cn.com.callback

import cn.com.elite.EliteBean
import cn.com.kh.KHUtil
import net.sf.json.JSONObject
import net.sf.json.JSONArray
import org.apache.commons.logging.Log
import org.apache.commons.logging.LogFactory
import org.springframework.jdbc.core.JdbcTemplate

import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * 工单流程轨迹图
 */

public class apiWoStepTrail implements ServiceBackInvoke {
    private static final Log log = LogFactory.getLog(apiWoStepTrail.class);

    public String doCallBack(EliteBean eliteBean, HttpServletRequest request, HttpServletResponse response) {

        long startTime = System.currentTimeMillis();
        response.setCharacterEncoding("UTF-8");
        response.setContentType("application/json;charset=utf-8");

        JdbcTemplate jt = new JdbcTemplate(eliteBean.getDataSource());

        // 初始化返回参数
        JSONObject result = new JSONObject();

        try {
            String obj_guid = request.getParameter("obj_guid"); //工单Guid
            String op_type = request.getParameter("op_type"); //结案
            log.debug("工单Guid:" + obj_guid);
            log.debug("工单类型:" + op_type);

            if (op_type == "path") {
                result = pathMode(jt, obj_guid);
            } else if(op_type == "multi_pass"){
                result = multiPass(jt, obj_guid);
            }else {
                result = stepMode(jt, obj_guid);
            }

        } catch (Exception e) {
            result.put("code", "0");
            result.put("msg", e.getMessage());
        }
        return result.toString();
    }

    // 工单预设路径模式
    public static JSONObject pathMode(JdbcTemplate jt, String obj_guid) {
        // 初始化返回参数
        JSONObject result = new JSONObject();

        JSONArray state = new JSONArray();
        JSONArray edg = new JSONArray();

        JSONObject startJson = new JSONObject();
        startJson.put("id", 0);
        startJson.put("label", "开始");
        startJson.put("shape", "ellipse");
        startJson.put("style", "fill:#63B8FF;stroke:#63B8FF");//边框样式
        startJson.put("labelStyle", "fill:#afa");
        state.add(startJson);
/*
        // 查询工单已有轨迹
        String getNodesSQL = '''Select 
            Rank() Over(Order By R1.Nodemap_Id Desc) As Rank_Id,
            R1.Nodemap_Id,
            R1.Nodemapname,
            Case
                When R3.Nodemap_Id Is Not Null And R3.Node_Type = 'TO' Then 'fill:#00FF7F;stroke:#00FF7F\'
                When R3.Nodemap_Id Is Not Null Then 'fill:#335684;stroke:#335684\'
                Else 'fill:#eeeeef;stroke:#eeeeef\'
                End As Node_Style,
            Case
                When R3.Nodemap_Id Is Not Null Then 'fill:#FFFFFF\'
                Else 'fill:#4a4e4a\'
                End As Nodelabel_Style,
            R4.Staffname,
            R4.Modifieddate,
            R4.Comments
        From Wo3_Node_Map R1
        Left Join Objective R2 On R1.Workorderframe_Id = R2.Objectivetype_Id And R1.Map_Id = R2.Map_Id
        Left Join (Select Distinct From_Stepidmap As Nodemap_Id, 'FROM' As Node_Type 
            From Workorderpath3 
            Where Workorder_Guid = ?
            Union
            Select Distinct To_Stepidmap As Nodemap_Id, 'TO' As Node_Type 
            From Workorderpath3 
            Where Workorder_Guid = ?
                And To_Stepidmap Not In (Select Distinct From_Stepidmap From Workorderpath3 Where Workorder_Guid = ?)
        ) R3 On R1.Nodemap_Id = R3.Nodemap_Id
        Left Join (Select R1.Workorderstep_Guid,
                    R1.From_Stepidmap,
                    R1.To_Stepidmap,
                    R1.Oldhandlegroup_Id,
                    R1.Oldhandleby_Id,
                    R3.Staffname,
                    R1.Handlegroup_Id,
                    R1.Handleby_Id,
                    R1.Comments,
                    Date_Format(R1.Modifieddate, '%Y-%m-%d %H:%i') As Modifieddate
            From Workorderstep3 R1
            Left Join (Select 
                    From_Stepidmap, 
                    To_Stepidmap, 
                    Max(Modifieddate) As Modifieddate 
                From Workorderstep3 
                Where Workorder_Guid = ? 
                Group By From_Stepidmap, To_Stepidmap
            ) R2 On R1.From_Stepidmap = R2.From_Stepidmap And R1.To_Stepidmap = R2.To_Stepidmap And R1.Modifieddate = R2.Modifieddate
            Left Join Staff R3 On R1.Oldhandleby_Id = R3.Staff_Id
            Where R1.Workorder_Guid = ?
            And R2.Modifieddate Is Not Null
        ) R4 On R3.Nodemap_Id = R4.From_Stepidmap
        Where R2.Objective_Guid = ?''';
*/

        // 查询工单已有轨迹
        String getNodesSQL = '''Select 
            Rank() Over(Order By R1.Nodemap_Id Desc) As Rank_Id,
            R1.Nodemap_Id,
            R1.Nodemapname,
            Case
                When R3.Nodemap_Id Is Not Null And R3.Node_Type = 'TO' Then 'fill:#00FF7F;stroke:#00FF7F\'
                When R3.Nodemap_Id Is Not Null Then 'fill:#335684;stroke:#335684\'
                Else 'fill:#eeeeef;stroke:#eeeeef\'
                End As Node_Style,
            Case
                When R3.Nodemap_Id Is Not Null Then 'fill:#FFFFFF\'
                Else 'fill:#4a4e4a\'
                End As Nodelabel_Style,
            R4.Staffname,
            R4.Modifieddate,
            R4.Comments
        From Wo3_Node_Map R1
        Left Join Objective R2 On R1.Workorderframe_Id = R2.Objectivetype_Id And R1.Map_Id = R2.Map_Id
        Left Join ( Select Distinct From_Stepidmap As Nodemap_Id, 'FROM' As Node_Type 
            From Workorderstep3 
            Where Workorder_Guid = ?
            Union
            Select Distinct To_Stepidmap As Nodemap_Id, 'TO' As Node_Type 
            From Workorderstep3 
            Where Workorder_Guid = ?
                And To_Stepidmap Not In ( Select Distinct From_Stepidmap From Workorderstep3 Where Workorder_Guid = ? )
        ) R3 On R1.Nodemap_Id = R3.Nodemap_Id
        Left Join ( Select R1.Workorderstep_Guid,
                    R1.From_Stepidmap,
                    R1.To_Stepidmap,
                    R1.Oldhandlegroup_Id,
                    R1.Oldhandleby_Id,
                    R3.Staffname,
                    R1.Handlegroup_Id,
                    R1.Handleby_Id,
                    R1.Comments,
                    Date_Format(R1.Modifieddate, '%Y-%m-%d %H:%i') As Modifieddate
            From Workorderstep3 R1
            Left Join ( Select 
                    From_Stepidmap, 
                    To_Stepidmap, 
                    Max(Modifieddate) As Modifieddate 
                From Workorderstep3 
                Where Workorder_Guid = ? 
                Group By From_Stepidmap, To_Stepidmap
            ) R2 On R1.From_Stepidmap = R2.From_Stepidmap And R1.To_Stepidmap = R2.To_Stepidmap And R1.Modifieddate = R2.Modifieddate
            Left Join Staff R3 On R1.Oldhandleby_Id = R3.Staff_Id
            Where R1.Workorder_Guid = ?
            And R2.Modifieddate Is Not Null
        ) R4 On R3.Nodemap_Id = R4.From_Stepidmap
        Where R2.Objective_Guid = ?''';

        List<Map<String, Object>> getNodesList = jt.queryForList(getNodesSQL, obj_guid, obj_guid, obj_guid, obj_guid, obj_guid, obj_guid);
        log.debug("查询工单已有轨迹:" + getNodesList.toString());

        // 查询工单流程路径
        String getLinksSQL = '''Select R1.Linkmap_Id, R1.Linkmapname, R1.Source_Id, R1.Target_Id, R1.Alwaysopen
                                  From Wo3_Link_Map R1
                                  Left Join Objective R2 On R1.Workorderframe_Id = R2.Objectivetype_Id And R1.Map_Id = R2.Map_Id
                                 Where R2.Objective_Guid = ?''';

        List<Map<String, Object>> getLinksList = jt.queryForList(getLinksSQL, obj_guid);
        log.debug("查询工单流程路径:" + getLinksList.toString());

        // 处理节点数据
        int nodesCount = getNodesList.size();
        for (Map<String, Object> getNodesMap : getNodesList) {
            JSONObject woDealJson = new JSONObject();

            int Rank_Id = Integer.parseInt(getNodesMap.get("Rank_Id").toString());
            String Nodemapname = String.valueOf(getNodesMap.get("Nodemapname"));
            String Modifieddate = String.valueOf(getNodesMap.get("Modifieddate"));
            String Comments = String.valueOf(getNodesMap.get("Comments"));
            String Staffname = String.valueOf(getNodesMap.get("Staffname"));
            String Node_Style = String.valueOf(getNodesMap.get("Node_Style"));
            String NodeLabel_Style = String.valueOf(getNodesMap.get("NodeLabel_Style"));

            String Label_Node = "🟠" + Nodemapname;
            String Label_Modifieddate = KHUtil.isNull(Modifieddate) ? "" : "\n📆" + Modifieddate;
            //String Label_Comments = KHUtil.isNull(Comments) ? "" : "\n📝" + Comments;
            String Label_Staffname = KHUtil.isNull(Staffname) ? "" : "\n🤵" + Staffname + " 已审核";

            String NodeLabel = "";
            if (!KHUtil.isNull(Modifieddate) && Modifieddate != "null") {
                //NodeLabel = Label_Node + Label_Modifieddate + Label_Comments;
                NodeLabel = Label_Node + Label_Modifieddate + Label_Staffname;
            } else {
                NodeLabel = Label_Node;
                Label_Modifieddate = "";
                //Label_Comments = "";
                Label_Staffname = "";
            }

            woDealJson.put("id", Rank_Id);
            woDealJson.put("label", NodeLabel);
            woDealJson.put("shape", "rect");
            woDealJson.put("style", Node_Style);
            woDealJson.put("labelStyle", NodeLabel_Style);
            //woDealJson.put("comment", Label_Comments);
            woDealJson.put("Staffname", Label_Staffname);

            state.add(woDealJson);

        }

        JSONObject endJson = new JSONObject();
        endJson.put("id", nodesCount + 1);
        endJson.put("label", "结束");
        endJson.put("shape", "ellipse");
        endJson.put("style", "fill:#63B8FF;stroke:#63B8FF");
        endJson.put("labelStyle", "fill:#afa");
        state.add(endJson);

        // 处理节点连接线
        int linksCount = getLinksList.size();
        for (Map<String, Object> getLinksMap : getLinksList) {
            JSONObject linkJson = new JSONObject();

            String Linkmap_Id = getLinksMap.get("Linkmap_Id").toString();
            String Linkmapname = getLinksMap.get("Linkmapname").toString();
            String Source_Id = getLinksMap.get("Source_Id").toString();
            String Target_Id = getLinksMap.get("Target_Id").toString();
            String Alwaysopen = getLinksMap.get("Alwaysopen").toString();
            log.debug("当前节点连接线:" + getLinksMap.toString());

            int i_Source_Id = 0;
            int i_Target_Id = nodesCount + 1;
            for (Map<String, Object> getNodesMap : getNodesList) {
                int Rank_Id = Integer.parseInt(getNodesMap.get("Rank_Id").toString());
                String Nodemap_Id = getNodesMap.get("Nodemap_Id").toString();
                if (Nodemap_Id == Source_Id) {
                    i_Source_Id = Rank_Id;
                }
                if (Nodemap_Id == Target_Id) {
                    i_Target_Id = Rank_Id;
                }
            }
            log.debug("转换节点连接线-源ID:" + i_Source_Id + " 目标ID:" + i_Target_Id);

            linkJson.put("source", i_Source_Id);
            linkJson.put("target", i_Target_Id);
            linkJson.put("label", Linkmapname);
            edg.add(linkJson);

        }

        result.put("code", 1);
        result.put("msg", "成功");
        result.put("state", state);
        result.put("edg", edg);

        return result;
    }

    // 工单非固定预设路径模式（多流程工单）
    public static JSONObject multiPass(JdbcTemplate jt, String obj_guid) {
        // 初始化返回参数
        JSONObject result = new JSONObject();

        JSONArray state = new JSONArray();
        JSONArray edg = new JSONArray();

        JSONObject startJson = new JSONObject();
        startJson.put("id", 0);
        startJson.put("label", "开始");
        startJson.put("shape", "ellipse");
        startJson.put("style", "fill:#63B8FF;stroke:#63B8FF");//边框样式
        startJson.put("labelStyle", "fill:#afa");
        state.add(startJson);

        // 查询工单已有轨迹
        String getNodesSQL = '''Select 
            Rank() Over(Order By R1.Nodemap_Id Desc) As Rank_Id,
            R1.Nodemap_Id,
            R1.Nodemapname,
            Case
                When R3.Nodemap_Id Is Not Null And R3.Node_Type = 'TO' Then 'fill:#00FF7F;stroke:#00FF7F\'
                When R3.Nodemap_Id Is Not Null Then 'fill:#335684;stroke:#335684\'
                Else 'fill:#eeeeef;stroke:#eeeeef\'
                End As Node_Style,
            Case
                When R3.Nodemap_Id Is Not Null Then 'fill:#FFFFFF\'
                Else 'fill:#4a4e4a\'
                End As Nodelabel_Style,
            R4.Staffname,
            R4.Modifieddate,
            R4.Comments
        From Wo3_Node_Map R1
        Left Join Objective R2 On R1.Workorderframe_Id = R2.Objectivetype_Id And R1.Map_Id = R2.Map_Id
        Left Join ( Select Distinct From_Stepidmap As Nodemap_Id, 'FROM' As Node_Type 
            From Workorderstep3 
            Where Workorder_Guid = ?
            Union
            Select Distinct To_Stepidmap As Nodemap_Id, 'TO' As Node_Type 
            From Workorderstep3 
            Where Workorder_Guid = ?
                And To_Stepidmap Not In ( Select Distinct From_Stepidmap From Workorderstep3 Where Workorder_Guid = ? )
        ) R3 On R1.Nodemap_Id = R3.Nodemap_Id
        Left Join ( Select R1.Workorderstep_Guid,
                    R1.From_Stepidmap,
                    R1.To_Stepidmap,
                    R1.Oldhandlegroup_Id,
                    R1.Oldhandleby_Id,
                    R3.Staffname,
                    R1.Handlegroup_Id,
                    R1.Handleby_Id,
                    R1.Comments,
                    Date_Format(R1.Modifieddate, '%Y-%m-%d %H:%i') As Modifieddate
            From Workorderstep3 R1
            Left Join ( Select 
                    From_Stepidmap, 
                    To_Stepidmap, 
                    Max(Modifieddate) As Modifieddate 
                From Workorderstep3 
                Where Workorder_Guid = ? 
                Group By From_Stepidmap, To_Stepidmap
            ) R2 On R1.From_Stepidmap = R2.From_Stepidmap And R1.To_Stepidmap = R2.To_Stepidmap And R1.Modifieddate = R2.Modifieddate
            Left Join Staff R3 On R1.Oldhandleby_Id = R3.Staff_Id
            Where R1.Workorder_Guid = ?
            And R2.Modifieddate Is Not Null
        ) R4 On R3.Nodemap_Id = R4.From_Stepidmap
        Where R4.Staffname is not null And R2.Objective_Guid = ?''';

        List<Map<String, Object>> getNodesList = jt.queryForList(getNodesSQL, obj_guid, obj_guid, obj_guid, obj_guid, obj_guid, obj_guid);
        log.debug("查询工单已有轨迹:" + getNodesList.toString());

        // 查询工单流程历史路径
        String getLinksSQL = '''Select 
                    R0.Map_Id As Linkmap_Id, 
                    R1.From_Stepidmap As Source_Id, 
                    R1.To_Stepidmap As Target_Id, 
                    R5.Workorderstepstatusdesc As Linkmapname
                From Workorderstep3 R1
                Left Join Objective R0 On R1.Workorder_Guid = R0.Objective_Guid
                Left Join Sysc_Workorderstepstatus R5 On R1.Workorderstepstatus = R5.Workorderstepstatus_Id
                Where R1.Workorder_Guid = ?
                Order By R1.Modifieddate''';

        List<Map<String, Object>> getLinksList = jt.queryForList(getLinksSQL, obj_guid);
        log.debug("查询工单流程路径:" + getLinksList.toString());

        // 处理节点数据
        int nodesCount = getNodesList.size();
        for (Map<String, Object> getNodesMap : getNodesList) {
            JSONObject woDealJson = new JSONObject();

            int Rank_Id = Integer.parseInt(getNodesMap.get("Rank_Id").toString());
            String Nodemapname = String.valueOf(getNodesMap.get("Nodemapname"));
            String Modifieddate = String.valueOf(getNodesMap.get("Modifieddate"));
            String Comments = String.valueOf(getNodesMap.get("Comments"));
            String Staffname = String.valueOf(getNodesMap.get("Staffname"));
            String Node_Style = String.valueOf(getNodesMap.get("Node_Style"));
            String NodeLabel_Style = String.valueOf(getNodesMap.get("NodeLabel_Style"));

            String Label_Node = "🟠" + Nodemapname;
            String Label_Modifieddate = KHUtil.isNull(Modifieddate) ? "" : "\n📆" + Modifieddate;
            //String Label_Comments = KHUtil.isNull(Comments) ? "" : "\n📝" + Comments;
            String Label_Staffname = KHUtil.isNull(Staffname) ? "" : "\n🤵" + Staffname + " 已审核";

            String NodeLabel = "";
            if (!KHUtil.isNull(Modifieddate) && Modifieddate != "null") {
                //NodeLabel = Label_Node + Label_Modifieddate + Label_Comments;
                NodeLabel = Label_Node + Label_Modifieddate + Label_Staffname;
            } else {
                NodeLabel = Label_Node;
                Label_Modifieddate = "";
                //Label_Comments = "";
                Label_Staffname = "";
            }

            woDealJson.put("id", Rank_Id);
            woDealJson.put("label", NodeLabel);
            woDealJson.put("shape", "rect");
            woDealJson.put("style", Node_Style);
            woDealJson.put("labelStyle", NodeLabel_Style);
            //woDealJson.put("comment", Label_Comments);
            woDealJson.put("Staffname", Label_Staffname);

            state.add(woDealJson);

        }

        JSONObject endJson = new JSONObject();
        endJson.put("id", nodesCount + 1);
        endJson.put("label", "结束");
        endJson.put("shape", "ellipse");
        endJson.put("style", "fill:#63B8FF;stroke:#63B8FF");
        endJson.put("labelStyle", "fill:#afa");
        state.add(endJson);

        // 处理节点连接线
        int linksCount = getLinksList.size();
        for (Map<String, Object> getLinksMap : getLinksList) {
            JSONObject linkJson = new JSONObject();

            String Linkmap_Id = getLinksMap.get("Linkmap_Id").toString();
            String Linkmapname = getLinksMap.get("Linkmapname").toString();
            String Source_Id = getLinksMap.get("Source_Id").toString();
            String Target_Id = getLinksMap.get("Target_Id").toString();
            log.debug("当前节点连接线:" + getLinksMap.toString());

            int i_Source_Id = 0;
            int i_Target_Id = nodesCount + 1;
            for (Map<String, Object> getNodesMap : getNodesList) {
                int Rank_Id = Integer.parseInt(getNodesMap.get("Rank_Id").toString());
                String Nodemap_Id = getNodesMap.get("Nodemap_Id").toString();
                if (Nodemap_Id == Source_Id) {
                    i_Source_Id = Rank_Id;
                }
                if (Nodemap_Id == Target_Id) {
                    i_Target_Id = Rank_Id;
                }
            }
            log.debug("转换节点连接线-源ID:" + i_Source_Id + " 目标ID:" + i_Target_Id);

            linkJson.put("source", i_Source_Id);
            linkJson.put("target", i_Target_Id);
            linkJson.put("label", Linkmapname);
            edg.add(linkJson);

        }

        result.put("code", 1);
        result.put("msg", "成功");
        result.put("state", state);
        result.put("edg", edg);

        return result;
    }

    // 工单历史轨迹模式
    public static JSONObject stepMode(JdbcTemplate jt, String obj_guid) {
        // 初始化返回参数
        JSONObject result = new JSONObject();

        JSONArray state = new JSONArray();
        JSONArray edg = new JSONArray();

        JSONObject startJson = new JSONObject();
        startJson.put("id", 0);
        startJson.put("label", "开始");
        startJson.put("shape", "ellipse");
        startJson.put("style", "fill:#63B8FF;stroke:#63B8FF");
        startJson.put("labelStyle", "fill:#afa");
        state.add(startJson);

        // 查询工单已有轨迹
        String woDealSQL = '''Select R1.Workorderstep_Guid,
                               R1.Oldhandlegroup_Id,
                               R1.Oldhandleby_Id,
                               R1.Handlegroup_Id,
                               R1.Handleby_Id,
                               R0.Map_Id,
                               R1.From_Stepidmap,
                               R1.To_Stepidmap,
                               R4.Nodemapname,
                               R2.Rolegroupdescription,
                               R3.Staffname,
                               R1.Comments,
                               R1.Modifieddate,
                               R5.Workorderstepstatusdesc As Workorderstepstatus
                          From Workorderstep3 R1
                          Left Join Rolegroup R2 On R1.Oldhandlegroup_Id = R2.Rolegroup_Id
                          Left Join Staff R3 On R1.Oldhandleby_Id = R3.Staff_Id
                          Left Join Objective R0 On R1.Workorder_Guid = R0.Objective_Guid
                          Left Join Wo3_Node_Map R4 On R1.From_Stepidmap = R4.Nodemap_Id And R0.Map_Id = R4.Map_Id
                          Left Join Sysc_Workorderstepstatus R5 On R1.Workorderstepstatus = R5.Workorderstepstatus_Id
                         Where R1.Workorder_Guid = ?
                         Order By R1.Modifieddate''';

        List<Map<String, Object>> woDealList = jt.queryForList(woDealSQL, obj_guid);

        int linkCount = woDealList.size();
        int linkNum = 0;
        String oldStepID = "Start";
        for (Map<String, Object> woDealMap : woDealList) {
            JSONObject linkJson = new JSONObject();
            JSONObject woDealJson = new JSONObject();
            String Workorderstep_Guid = woDealMap.get("Workorderstep_Guid").toString();
            String Map_Id = woDealMap.get("Map_Id").toString();
            String From_Stepidmap = woDealMap.get("From_Stepidmap").toString();
            String To_Stepidmap = woDealMap.get("To_Stepidmap").toString();
            String Nodemapname = woDealMap.get("Nodemapname").toString();
            String Staffname = woDealMap.get("Staffname").toString();
            String Modifieddate = woDealMap.get("Modifieddate").toString();
            String Comments = woDealMap.get("Comments").toString();
            String Workorderstepstatus = woDealMap.get("Workorderstepstatus").toString();

            woDealJson.put("id", linkNum + 1);
            woDealJson.put("label", "🟠" + Nodemapname + "\n📆" + Modifieddate + "\n📝" + Comments + "");
            woDealJson.put("shape", "rect");
            woDealJson.put("style", "fill:#335684;stroke:#335684");
            woDealJson.put("labelStyle", "fill:#FFFFFF");

            state.add(woDealJson);

            if (linkNum == 0) {
                linkJson.put("source", 0);
                linkJson.put("target", linkNum + 1);
                linkJson.put("label", "");
                edg.add(linkJson);
            } else {

                linkJson.put("source", linkNum);
                linkJson.put("target", linkNum + 1);
                linkJson.put("label", Workorderstepstatus);
                edg.add(linkJson);
                if (linkNum + 1 == linkCount) {
                    linkJson.put("source", linkNum + 1);
                    linkJson.put("target", linkCount + 1);
                    linkJson.put("label", "");
                    edg.add(linkJson);
                }
            }

            linkNum++;
            oldStepID = Workorderstep_Guid;

        }

        JSONObject endJson = new JSONObject();
        endJson.put("id", linkCount + 1);
        endJson.put("label", "结束");
        endJson.put("shape", "ellipse");
        endJson.put("style", "fill:#63B8FF;stroke:#63B8FF");
        endJson.put("labelStyle", "fill:#afa");
        state.add(endJson);

        result.put("code", 1);
        result.put("msg", "成功");
        result.put("state", state);
        result.put("edg", edg);

        return result;
    }
}

